<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>事件处理</title>
	</head>
	<body>
		<div id="root"></div>

		<script
			type="text/javascript"
			src="./components/react.development.js"
		></script>
		<script
			type="text/javascript"
			src="./components/react-dom.development.js"
		></script>
		<script type="text/javascript" src="./components/babel.min.js"></script>

		<script type="text/babel">
			/*
      事件处理
      React 元素的事件处理和 DOM 元素的很相似，但是有一点语法上的不同：

      React 事件的命名采用小驼峰式（camelCase），而不是纯小写。
      使用 JSX 语法时你需要传入一个函数作为事件处理函数，而不是一个字符串。

      在react中:
      <button onClick={activateLasers}>Activate Lasers</button>        
    */

    class Toggle extends React.Component {
      constructor (props) {
        super(props);
        this.state = { isToggleOn: true };
        
        // 必须谨慎对待JSX回调函数中的this, 因为class的方法默认不会绑定this。如果忘记绑定this.handleClick并传入了onClick，调用函数的时候this的值为undefined;

        // 为了在回调中使用 `this`, 这个绑定是必不可少的
        this.handleClick = this.handleClick.bind(this);

        //这并不是 React 特有的行为；这其实与 JavaScript 函数工作原理有关。通常情况下，如果你没有在方法后面添加 ()，例如 onClick={this.handleClick}，你应该为这个方法绑定 this。

        // 如果觉得使用 bind 很麻烦，这里有两种方式可以解决。如果你正在使用实验性的 public class fields 语法，你可以使用 class fields 正确的绑定回调函数：
        
        // 此语法确保  `handleClick` 内的 `this`已被绑定。
        // 注意：这是 *实验性* 语法。
        // handleClick = () => {
        //   console.log('this is:', this)
        // }
      }

      handleClick () {
        this.setState( state => ({
          isToggleOn: !state.isToggleOn
        }))
      }

      render () {
        return (
          <button onClick={this.handleClick}>{this.state.isToggleOn ? 'ON' : 'OFF'}</button>

          // 此语法确保 `handleClick` 内的 `this` 已被绑定。
          // <button onClick={()=>this.handleClick()}>{this.state.isToggleOn ? 'ON' : 'OFF'}</button>

          // 向事件处理程序传递参数
          // <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
          // <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

          // 上述两种方式是等价的，分别通过箭头函数和 Function.prototype.bind 来实现。

          // 在这两种情况下，React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式，事件对象必须显式的进行传递，而通过 bind 的方式，事件对象以及更多的参数将会被隐式的进行传递。
        )
      }
    }

    ReactDOM.render(
      <Toggle />,
      document.getElementById('root')
    )
      
		</script>
	</body>
</html>
